package com.sunfeng.gulimall.search.thread;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Author : 清风冷影
 * @Description: ]
 * @Date : 2021/11/15  21:50
 */
@Slf4j
public class ThreadTest1 {
    public static ExecutorService executor = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        log.info("开始");
        /**
         * 任务组合
         * 线程并行执行完成，并且执行新任务action，新任务无入参，无返回值
         * runAfterBoth runAfterBothAsync  runAfterBothAsync
         * 线程并行执行完成，并且执行新任务action，新任务有入参，无返回值
         * thenAcceptBoth  thenAcceptBothAsync  thenAcceptBothAsync
         * 线程并行执行完成，并且执行新任务action，新任务有入参，有返回值
         *  thenCombine  thenCombineAsync thenCombineAsync
         *
         */
// 任务1
        CompletableFuture<Integer> future01 = CompletableFuture.supplyAsync(() -> {
            log.info("任务1线程：" + Thread.currentThread().getId());
            int i = 10 / 4;
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info("任务1结束：");

            return i;
        }, executor);

// 任务2
        CompletableFuture<String> future02 = CompletableFuture.supplyAsync(() -> {
            log.info("任务2线程：" + Thread.currentThread().getId());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info("任务2结束");

            return "Hello";
        }, executor);
        // 任务一和任务二都完成 在不使用任务返回值的情况下执行任务三 ,并且任务三没有返回值
        // future01.runAfterBoth(future02,()-> System.out.println("开始任务三"));

        // 任务一和任务二都完成 使用任务1和任务2的返回值情况下执行任务3，并且任务3没有返回值

//        future01.thenAcceptBoth(future02,(f1,f2)->{
//            System.out.println("任务三开始，执行拼接任务1 与任务2的 结果");
//            System.out.println(f1+f2);
//        });
        // 任务一和任务二都完成 使用任务1和任务2的返回值情况下执行任务3，并且任务3有返回值

        CompletableFuture<String> stringCompletableFuture = future01.thenCombineAsync(future02, (f1, f2) -> {
            log.info("其他两个任务都已经完成");
            return f1 + f2;
        });
        System.out.println(stringCompletableFuture.get());

        executor.shutdown();
    }
}
